﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using InternRegistration.Model;
using System.Windows.Input;
using InternRegistration.Common;
using InternRegistration.View;
using System.Windows;
using System.Collections.ObjectModel;
using InternRegistration.DataBase;
using System.Windows.Controls;

namespace InternRegistration.ViewModel
{
    class DisplayViewModel : ViewModelBase
    {
        /* DisplayViewModel of system used for registration and viewing process of Interns. */
               
        #region Private Variables
        private readonly Intern dominatorIntern; //Delegate for Intern
        private readonly InternManager internManager;

        private bool _isEnabled;
        private bool _isUpdateEnabled;

        private ICommand _selectAllCommand;

        private ICommand _unselectAllCommand;  // selection options for programminglanguageslist

        private ICommand _addCommand; //add new language to system

        private string _newProgrammingLanguage;

        private Visibility _updateVisibility = Visibility.Visible;

        private SelectionList<string> programmingLanguagesList;


        #endregion

        #region Constructors
        //constructor for new registration page
        public DisplayViewModel()
        {
            dominatorIntern = new Intern();
            internManager = new InternManager();
            DepartmentList = new List<string>();
            DepartmentList.Add("Bölüm Seçiniz");
            DepartmentList.Add("Bilgisayar Mühendisliği");          // department list
            DepartmentList.Add("Elektrik Elektronik Mühendisliği");
            DepartmentList.Add("Fizik");
            DepartmentList.Add("Diğer");

            GradeList = new List<string>();
            GradeList.Add("Lütfen Sınıf Seçiniz");
            GradeList.Add("2.Sınıf");  
            GradeList.Add("3.Sınıf");                               //grade list 
            GradeList.Add("4.Sınıf");
            dominatorIntern.InternshipStarting = DateTime.Today;
            dominatorIntern.InternshipEnding = DateTime.Today;
            dominatorIntern.BirthOfDay = DateTime.Today;
            ImageSource = "/Images/default_image.png";
            IsEnabled = true;
            dominatorIntern.Department = departmentList[0];
            dominatorIntern.Grade = gradeList[0];

            string[] ListOfLanguages = { };
            ProgrammingLanguagesList = new SelectionList<string>(ListOfLanguages);

            ChangeUpdateVisibility = Visibility.Hidden;

            //OnPropertyChanged("ProgrammingLanguagesList");
            foreach (var language in DBControl.Instance.SelectLanguagesFromDatabase())
            {
                ProgrammingLanguagesList.Add(language);
            }

        }




        //Constructor for displaying , editing registrated Interns 
        public DisplayViewModel(Intern Selected, bool editable)
            : this()
        {

            IsEnabled = false;
            dominatorIntern = Selected;
            OnPropertyChanged("ProgrammingLanguages");
            ChangeUpdateVisibility = Visibility.Visible;
            IsUpdateEnabled = true;
            ChangeSaveVisibility = Visibility.Hidden;

            foreach (var userItem in dominatorIntern.ProgrammingLanguages.Split(','))
            {
                foreach (var langItem in ProgrammingLanguagesList)
                {
                    if (langItem.Item.Trim() == userItem.Trim())
                    {
                        langItem.IsSelected = true;  // tick known languages
                    }
                }
            }
        }

        #endregion

        #region Properties

       


        public long Id
        {
            get { return dominatorIntern.Id; }
            set
            {
                dominatorIntern.Id = value;
                OnPropertyChanged("Id");
            }
        } // end ID Property


        public string Name
        {
            get { return dominatorIntern.Name; }
            set
            {
                dominatorIntern.Name = value;
                OnPropertyChanged("Name");
            }

        } //end Name Property

        public string Surname
        {
            get { return dominatorIntern.Surname; }
            set
            {
                dominatorIntern.Surname = value;
                OnPropertyChanged("Surname");
            }

        }


        public DateTime BirthOfDay
        {
            get { return dominatorIntern.BirthOfDay; }
            set
            {
                dominatorIntern.BirthOfDay = value;
                OnPropertyChanged("BirthOfDay");
            }

        }

        public string Address
        {
            get { return dominatorIntern.Address; }
            set
            {
                dominatorIntern.Address = value;
                OnPropertyChanged("Address");
            }
        } // end Address Property

        public string TelephoneNumber
        {
            get { return dominatorIntern.TelephoneNumber; }
            set
            {
                dominatorIntern.TelephoneNumber = value;
                OnPropertyChanged("TelephoneNumber");
            }

        } // end Telephone Number

        public string Email
        {
            get { return dominatorIntern.Email; }
            set
            {
                dominatorIntern.Email = value;
                OnPropertyChanged("Email");
            }
        } // end Email

        public string School
        {
            get { return dominatorIntern.School; }
            set
            {
                dominatorIntern.School = value;
                OnPropertyChanged("School");
            }
        } // end School Property

        public List<string> departmentList { get; private set; }
        public List<string> DepartmentList
        {
            get { return departmentList; }
            set
            {
                departmentList = value;
                OnPropertyChanged("Department");
            }
        }

        public List<string> gradeList { get; private set; }
        public List<string> GradeList
        {
            get { return gradeList; }
            set
            {
                gradeList = value;
                OnPropertyChanged("Grade");
            }

        }


        public string Department
        {
            get { return dominatorIntern.Department; }
            set
            {
                dominatorIntern.Department = value;
                OnPropertyChanged("Department");
            }

        } // end Department


        public string Grade
        {
            get { return dominatorIntern.Grade; }
            set
            {
                dominatorIntern.Grade = value;
                OnPropertyChanged("Grade");
            }

        } // end Grade


        public double GradePointAverage
        {
            get { return dominatorIntern.GradePointAverage; }
            set
            {
                dominatorIntern.GradePointAverage = value;
                OnPropertyChanged("GradePointAverage");
            }

        }  // end GPA


        public string Supervisor
        {
            get { return dominatorIntern.Supervisor; }
            set
            {
                dominatorIntern.Supervisor = value;
                OnPropertyChanged("Supervisor");
            }

        }    // end supervisor


        public string ImageSource
        {
            get { return dominatorIntern.PicURL; }
            set
            {
                dominatorIntern.PicURL = value;
                OnPropertyChanged("ImageSource");
            }

        } // end ImageSource


        public DateTime InternshipStarting
        {
            get { return dominatorIntern.InternshipStarting; }
            set
            {
                dominatorIntern.InternshipStarting = value;
                OnPropertyChanged("InternshipStarting");
            }


        } //end InternshipStarting

        public string ProgrammingLanguages 
        {
            get { return dominatorIntern.ProgrammingLanguages; }
            set
            {
                dominatorIntern.ProgrammingLanguages = value;
                OnPropertyChanged("ProgrammingLanguages");
            }

        } // end programming languages

        public SelectionList<string> ProgrammingLanguagesList // list of languages
        {

            get { return programmingLanguagesList; }
            set { programmingLanguagesList = value; OnPropertyChanged("ProgrammingLanguagesList"); }

        }


        public string NewProgrammingLanguage // new programminglanguages added to database
        {
            get { return _newProgrammingLanguage; }
            set
            {
                if (value == _newProgrammingLanguage) return;
                _newProgrammingLanguage = value;
                OnPropertyChanged("_NewProgrammingLanguage");
            }
        }



        public string Comment // commnt about intern
        {
            get { return dominatorIntern.Comment; }
            set
            {
                dominatorIntern.Comment = value;
                OnPropertyChanged("Comment");
            }

        }
        public DateTime InternshipEnding
        {
            get { return dominatorIntern.InternshipEnding; }
            set
            {
                dominatorIntern.InternshipEnding = value;
                OnPropertyChanged("InternshipEnding");
            }


        } // end InternshipEnding
        public bool IsEnabled  // for viewing intern w/o enter info disable fields
        {

            get { return _isEnabled; }
            set
            {

                if (_isEnabled == value)
                {
                    return;
                }
                _isEnabled = value;
                OnPropertyChanged("IsEnabled");
            }

        }

        public bool IsUpdateEnabled // enable to save changes
        {

            get { return _isUpdateEnabled; }
            set
            {

                if (_isUpdateEnabled == value)
                {
                    return;
                }


                _isUpdateEnabled = value;
                OnPropertyChanged("IsUpdateEnabled");
            }

        }

        public Visibility ChangeUpdateVisibility  // since savechanges is not seen in the register view its visibility binded here
        {   //ChangeUpdateVisibility
            get { return _updateVisibility; }
            set
            {
                _updateVisibility = value;
                this.OnPropertyChanged("ChangeUpdateVisibility");
            }
        }


        private Visibility _saveVisibility = Visibility.Visible;  // Save button is visible only for registration

        public Visibility ChangeSaveVisibility
        {   //ChangeUpdateVisibility
            get { return _saveVisibility; }
            set
            {
                _saveVisibility = value;
                this.OnPropertyChanged("ChangeSaveVisibility");
            }
        }

        #endregion

        #region SaveInternCommand    // SaveInternCommand first validates intern's informations then registers intern

        public bool CanSave()
        {
            if (internManager.CheckAdd(dominatorIntern))
            {

                return true;
            }
            else
                return false;
        }


        public void Save()
        {

            if (internManager.CheckAdd(dominatorIntern))
            {
                DBControl dbc = new DBControl();
                dbc.InsertIntern(dominatorIntern);
                OnPropertyChanged("SearchList");
                IsUpdateEnabled = false;


            }

            App.Current.Windows.Cast<Window>().Where(win => win is DisplayView).FirstOrDefault().Close();
            MessageBox.Show("Stajyer Başarıyla Kaydedildi.","Stajyer Kayıt");


        }

        RelayCommand _SaveInternCommand;
        public RelayCommand SaveInternCommand
        {
            get
            {
                if (_SaveInternCommand == null)
                {
                    _SaveInternCommand = new RelayCommand(p => this.Save(),
                        p => this.CanSave());
                }
                return _SaveInternCommand;
            }
        }

        #endregion

        #region EditCommand //EditCommand used for enabling fields on interface to update intern
        bool CanEdit()
        {
            return true;
        }

        RelayCommand _EditInternCommand;
        public RelayCommand EditInternCommand
        {
            get
            {
                if (_EditInternCommand == null)
                {
                    _EditInternCommand = new RelayCommand(p => this.Edit(),
                        p => this.CanEdit());
                }
                return _EditInternCommand;
            }
        }

        public void Edit()
        {

            IsEnabled = true;
            IsUpdateEnabled = true;


        }
        #endregion

        #region UpdateCommand  //UpdateCommand  for updating intern informations
        bool CanUpdate()
        {
            return true;
        }

        RelayCommand _UpdateCommand;  
        public RelayCommand UpdateCommand
        {
            get
            {
                if (_UpdateCommand == null)
                {
                    _UpdateCommand = new RelayCommand(p => this.Update(),
                        p => this.CanUpdate());
                }
                return _UpdateCommand;
            }
        }

        public void Update()
        {

            IsEnabled = true;
            DBControl.Instance.EditIntern(dominatorIntern, dominatorIntern.Id);
            MessageBox.Show("Stajyer Bigileri Güncellendi","Stajyer Güncelleme");

        }




        #endregion

        #region ClearCommand // ClearCommand used to clear the informations seen in the interface
        void Clear()
        {

            Id = 0;
            Name = "";
            Surname = "";
            BirthOfDay = DateTime.Today;
            Address = "";
            TelephoneNumber = "";
            Email = "";
            School = "";
            Department = "";
            Grade = "";
            GradePointAverage = 0.0;
            Supervisor = "";
            InternshipStarting = DateTime.Today;
            InternshipEnding = DateTime.Today;
            Comment = "";
            Department = DepartmentList[0];
            Grade = GradeList[0];
        }



        bool CanClear()
        {
            return true;
        }

        RelayCommand _ClearCommand;
        public RelayCommand ClearCommand
        {
            get
            {
                if (_ClearCommand == null)
                {
                    _ClearCommand = new RelayCommand(p => this.Clear(),
                        p => this.CanClear());
                }
                return _ClearCommand;
            }
        }

        #endregion

        #region CancelCommand //Used to backto SearchEntryView
        RelayCommand _CancelCommand;
        public RelayCommand CancelCommand
        {
            get
            {
                if (_CancelCommand == null)
                {
                    _CancelCommand = new RelayCommand(p => this.Cancel(),
                        p => this.CanCancel());
                }
                return _CancelCommand;
            }
        }

        bool CanCancel()
        {
            return true;
        }

        void Cancel()
        {
            App.Current.Windows.Cast<Window>().Where(win => win is DisplayView).FirstOrDefault().Close();
        }

        #endregion

        #region BrowseCommand //Used to browse image
        RelayCommand _BrowseCommand;
        public RelayCommand BrowseCommand
        {
            get
            {
                if (_BrowseCommand == null)
                {
                    _BrowseCommand = new RelayCommand(p => this.Browse(),
                        p => this.CanBrowse());
                }
                return _BrowseCommand;
            }
        }

        bool CanBrowse()
        {
            return true;
        }

        void Browse()
        {
            var filedialog = new Microsoft.Win32.OpenFileDialog();
            filedialog.FileName = "Resim"; // Default file name
            filedialog.DefaultExt = ".jpg"; // Default file extension
            filedialog.Filter = "JPEG Files (.jpg)|*.jpg"; // Filter files by extension


            Nullable<bool> fresult = filedialog.ShowDialog();

            if (fresult == true)
            {
                ImageSource = @"" + filedialog.FileName;
                OnPropertyChanged("ImageSource");
            }


        }

        #endregion

        #region DeleteCommand
        bool CanDelete()
        {
            return true;
        }

        RelayCommand _DeleteInternCommand;
        public RelayCommand DeleteInternCommand
        {
            get
            {
                if (_DeleteInternCommand == null)
                {
                    _DeleteInternCommand = new RelayCommand(p => this.Delete(),
                        p => this.CanDelete());
                }
                return _DeleteInternCommand;
            }
        }

        public void Delete()
        {

            DBControl.Instance.DeleteIntern(dominatorIntern, dominatorIntern.Id);
            Clear();
            MessageBox.Show("Stajyer Sistemden Silindi.","Stajyer Silme");

        }
        #endregion

        #region SaveLanguagesCommand
        bool CanLanguage()
        {

            return true;

        }

        RelayCommand _SaveLanguagesCommand;
        public RelayCommand SaveLanguagesCommand
        {
            get
            {
                if (_SaveLanguagesCommand == null)
                {
                    _SaveLanguagesCommand = new RelayCommand(p => this.Language(),
                        p => this.CanLanguage());
                }
                return _SaveLanguagesCommand;
            }
        }

        public void Language()
        {
            string seperator = ",";

            foreach (var item in ProgrammingLanguagesList.SelectedItems)
            {
                dominatorIntern.ProgrammingLanguages += item + seperator;
            }
            var SelectedLanguages = ProgrammingLanguagesList.SelectedItems.Count();
            MessageBox.Show(dominatorIntern.ProgrammingLanguages, "Seçilen Diller");


        }
        #endregion

        #region SelectAllCommand // to select all languages from the checklistbox
        public ICommand SelectAllCommand
        {
            get
            {
                if (_selectAllCommand == null)
                {
                    _selectAllCommand = new RelayCommand(param => ProgrammingLanguagesList.SelectAll());
                }
                return _selectAllCommand;
            }
        }

        #endregion

        #region AddCommand // To add new languages to database
        public ICommand AddCommand
        {
            get
            {
                if (_addCommand == null)
                {
                    _addCommand = new RelayCommand(param =>
                    {
                        if (NewProgrammingLanguage.Trim().Count() > 0 &&
                            !ProgrammingLanguagesList.Contains(NewProgrammingLanguage))
                        {
                            ProgrammingLanguagesList.Add(NewProgrammingLanguage.ToUpper());
                            OnPropertyChanged("ProgrammingLanguagesList");
                            //NewProgrammingLanguage = string.Empty;
                            DBControl.Instance.InsertNewLanguage(NewProgrammingLanguage.ToUpper());
                            MessageBox.Show(DBControl.Instance.SelectLanguagesFromDatabase().ToString());
                        }
                    });
                }
                return _addCommand;
            }
        }

        #endregion

        #region UnselectAllCommand  // Remove all language selection from the list
        public ICommand UnselectAllCommand
        {
            get
            {
                if (_unselectAllCommand == null)
                {
                    _unselectAllCommand = new RelayCommand(param => ProgrammingLanguagesList.UnselectAll());
                }
                return _unselectAllCommand;
            }
        }

        #endregion

    }
}